<?php

namespace App\Models;

use Throwable;
use App\Traits\Eth;
use Encore\Admin\Form;
use App\Support\Currency;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Notifications\Notifiable;

class EthRecord extends BaseModel
{
    use Eth;

    const TYPE_RECHARGE = 0; // 充值
    const TYPE_WITHDRAW = 1; // 提现

    const STATUS_UNCONFIRMED = 0;
    const STATUS_CONFIRMED   = 1;
    const STATUS_REJECT      = 2;
    const STATUS_ETH_CONFIRMED = 3;

    public static $statusMap = [
        self::STATUS_UNCONFIRMED => '未审核',
        self::STATUS_CONFIRMED   => '已审核',
        self::STATUS_REJECT      => '已驳回',
        self::STATUS_ETH_CONFIRMED => '等待区块链确认'
    ];

    public static $typeMap = [
        self::TYPE_RECHARGE => '充值',
        self::TYPE_WITHDRAW => '提现',
    ];

    protected $fillable = [
        'type',
        'value',
        'status',
        'user_id',
        'enable_value',
        'from_address',
        'to_address_id'
    ];

    use Notifiable {
        notify as protected laravelNotify;
    }

    public function notify($instance)
    {
        // 只有数据库类型通知才需提醒，Email 或者其他的都 Pass
        if (method_exists($instance, 'toDatabase')) {
            DB::table('admin_users')->increment('notification_count', 1);
        }

        $this->laravelNotify($instance);
    }

    /**
     * @param  Form  $form
     * @return bool
     * @throws Throwable
     */
    public function markAsRead(Form $form)
    {
        if ($form->model()->status != self::STATUS_UNCONFIRMED) {
            return false;
        }
        if ($form->status == self::STATUS_REJECT) {
            return true;
        }
        $model = $form->model();
        try {
            if ($model->type == self::TYPE_WITHDRAW) {
                DB::transaction(function () use ($model) {
                    $model->from_address = $this->withdraw(
                        $model->to_address_id, $model->enable_value);
                    $model->save();
                    $model->record()->create([
                        'type' => '提币',
                        'value' => $model->value,
                        'currency' => Currency::ETH,
                        'user_id' => $model->user_id
                    ]);
                });
                $model->user->addFreezeByCurrency(Currency::ETH, $model->value);
            } else {
                DB::transaction(function () use ($model) {
                    $model->status = EthRecord::STATUS_CONFIRMED;
                    $model->record()->create([
                        'type' => '充币',
                        'currency' => Currency::ETH,
                        'user_id' => $model->user_id,
                        'value' => $model->enable_value
                    ]);
                    $model->save();
                });
            }
        } catch (Throwable $exception) {
            Log::error("[eth_records.id => {$model->id}]");
            throw $exception;
        }
        return true;
    }

    public function record()
    {
        return $this->morphOne(Record::class, 'recordable');
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function link($params)
    {
        return route('ethrecord.show', $params);
    }

    public function toAddress()
    {
        return $this->belongsTo(Address::class, 'to_address_id')->withTrashed();
    }
}
